/** =====================================================
 * Copyright © hk. 2022-2025. All rights reserved.
 * File name  : gpio_in.c
 * Author     : 苏木
 * Date       : 2024-09-04
 * Version    :
 * Description:
 * ======================================================
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

static char gpio_in_path[100];

static int gpio_in_config(const char *attr, const char *val)
{
    int len = 0;
    int fd = -1;
    char file_path[100] = {0};

    sprintf(file_path, "%s/%s", gpio_in_path, attr);
    if (0 > (fd = open(file_path, O_WRONLY)))
    {
        perror("open error");
        return fd;
    }

    len = strlen(val);
    if (len != write(fd, val, len))
    {
        perror("write error");
        close(fd);
        return -1;
    }

    close(fd); // 关闭文件
    return 0;
}

int main(int argc, char *argv[])
{
    char val = 0;
    int fd = -1;
    char file_path[100] = {0};

    /* 校验传参 */
    if (2 != argc)
    {
        fprintf(stderr, "usage: %s <gpio>\n", argv[0]);
        exit(-1);
    }

    /* 判断指定编号的GPIO是否导出 */
    sprintf(gpio_in_path, "/sys/class/gpio/gpio%s", argv[1]);

    if (access(gpio_in_path, F_OK))
    { 
        // 如果目录不存在 则需要导出
        int len = 0;
        if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY)))
        {
            perror("open error");
            exit(-1);
        }

        len = strlen(argv[1]);
        if (len != write(fd, argv[1], len))
        { // 导出gpio
            perror("write error");
            close(fd);
            exit(-1);
        }

        close(fd); // 关闭文件
    }

    /* 配置为输入模式 */
    if (gpio_in_config("direction", "in"))
    {
        exit(-1);
    }

    /* 极性设置 */
    if (gpio_in_config("active_low", "0"))
    {
        exit(-1);
    }

    /* 配置为非中断方式 */
    if (gpio_in_config("edge", "none"))
    {
        exit(-1);
    }

    /* 读取GPIO电平状态 */
    sprintf(file_path, "%s/%s", gpio_in_path, "value");

    if (0 > (fd = open(file_path, O_RDONLY)))
    {
        perror("open error");
        exit(-1);
    }

    if (0 > read(fd, &val, 1))
    {
        perror("read error");
        close(fd);
        exit(-1);
    }

    printf("value: %c\n", val);

    /* 退出程序 */
    close(fd);
    exit(0);
}
